import {name} from "@/../package.json";

const [, minor] = process.env.VERSION.split(".");

// 表的结构实例
const tableSchemes = {
  router:{
    keyPath:"id",
  },
};


let dbContext: IDBDatabase;// 数据库上下文
const tryInitPromise = new Promise<IDBDatabase>((resolve, reject) => {
  const win = window as any;
  const indexedDb: IDBFactory = win.indexedDB || win.webkitIndexedDB || win.mozIndexedDB || win.msIndexedDB;

  if (indexedDb) {
    const request = indexedDb.open(`cache:${name}`, Number(minor) );

    request.onerror = function (evt) {
      reject(evt);
    };
    request.onsuccess = function () {
      // 打开数据库
      dbContext = request.result;
      resolve(dbContext);
    };
    // 监听版本升级事件
    request.onupgradeneeded = function () {
      //! 执行这里后才会走success
      dbContext = (event.target as any).result;
      //! 创建数据库表
      Object.keys(tableSchemes).forEach(item => {
        if (!dbContext.objectStoreNames.contains(item)) {
          dbContext.createObjectStore(item, tableSchemes[item]);
        }
      });

    };
  } else {
    reject("不支持的数据库");
  }
});

function getDbContext() {
  if (dbContext) {
    return Promise.resolve(dbContext);
  }
  return tryInitPromise;
}

export async function getTable<T = any>(table: keyof typeof tableSchemes) {
  const dbContext = await getDbContext();
  const add = (data: T, key?: IDBValidKey) => {
    const request = dbContext.transaction([table], "readwrite").objectStore(table).add(data, key);
    return new Promise<void>((resolve, reject) => {
      request.onerror = function (event) {
        reject(event);
      };

      request.onsuccess = function () {
        resolve();
      };
    });
  };
  const findByKey = (query: IDBValidKey|IDBKeyRange) => {
    const request = dbContext.transaction([table]).objectStore(table).get(query);
    return new Promise<T>((resolve, reject) => {
      request.onerror = function (event) {
        reject(event);
      };

      request.onsuccess = function (event) {
        resolve(request.result);
      };
    });
  };
  const readAll = () => {
    const request = dbContext.transaction([table]).objectStore(table).openCursor();

    return new Promise<T[]>((resolve, reject) => {
      request.onerror = function (event) {
        reject(event);
      };

      const data: T[] = [];
      request.onsuccess = function (event) {
        const cursor = (event.target as any).result;
        if (cursor) {
          data.push(cursor);
          cursor.continue();
        } else {
          // 数据读取完毕
          resolve(data);
        }
      };
    });
  };
  const update = (data: T, key?: IDBValidKey) => {
    const request = dbContext.transaction([table], "readwrite").objectStore(table).put(data, key);
    return new Promise<void>((resolve, reject) => {
      request.onerror = function (event) {
        reject(event);
      };

      request.onsuccess = function () {
        resolve();
      };
    });
  };
  const removeByKey = (query: IDBValidKey|IDBKeyRange) => {
    const request = dbContext.transaction([table], "readwrite").objectStore(table).delete(query);
    return new Promise<void>((resolve, reject) => {
      request.onerror = function (event) {
        reject(event);
      };

      request.onsuccess = function () {
        resolve();
      };
    });
  };
  const clear = () => {
    const request = dbContext.transaction([table], "readwrite").objectStore(table).clear();
    return new Promise<void>((resolve, reject) => {
      request.onerror = function (event) {
        reject(event);
      };

      request.onsuccess = function () {
        resolve();
      };
    });
  };

  return {
    add, findByKey, readAll, update, removeByKey, clear,
  };

}

